home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 17
/
CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso
/
CUCD
/
Programming
/
DiceSource
/
src
/
dd
/
loadseg.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-09-09
|
24KB
|
990 lines
/*
* (c)Copyright 1992-1997 Obvious Implementations Corp. Redistribution and
* use is allowed under the terms of the DICE-LICENSE FILE,
* DICE-LICENSE.TXT.
*/
#include "defs.h"
#include "dbug_protos.h"
// ************************************************************************
Prototype WORD RefreshHunks(WORD maxLines, BOOL fullRefresh, LONG index);
Prototype WORD RefreshSymbols(WORD maxLines, BOOL fullRefresh, LONG index);
Prototype LONG SymbolIndexOfAddr(ULONG val);
Prototype BOOL DownHunks(void);
Prototype BOOL UpHunks(void);
Prototype BOOL DownSymbol(void);
Prototype BOOL PageDownSymbol(void);
Prototype BOOL UpSymbol(void);
Prototype BOOL PageUpSymbol(void);
Local BOOL HunkError(ULONG hunkType);
Prototype BOOL DBugLoadSeg(char *filename);
Prototype void AllocateStack(void);
Prototype void ResetTarget(void);
Prototype DEBUG *FindDebug(ULONG address);
Prototype DEBUG *FindNearestDebug(ULONG address);
Prototype SOURCE *FindSource(DEBUG *debug, ULONG address);
Prototype char *FindSourceLine(DEBUG *debug, SOURCE *source);
Prototype __stkargs char *LookupValue(ULONG value);
Local char *LookupOffset(ULONG value,ULONG *symBuf);
Prototype ULONG *NearestSymbol(ULONG value);
Prototype char *NearestValue(ULONG value);
Local BOOL CompareLStrings(ULONG *s1, ULONG *s2);
Prototype BOOL LookupSymbol(char *symbol, ULONG *value);
Prototype BOOL LookupSymLen(char *symbol, UWORD len, ULONG *value);
Prototype int CountSymbols(void);
Prototype void CopySymbols(SYMLIST *symlist);
Prototype char *addscore(char *string);
Prototype char *addat(char *string);
// ************************************************************************
UBYTE *programStack = NULL;
UBYTE *programStackTop = NULL;
ULONG programStackSize = 32768;
// ************************************************************************
BOOL DownHunks(void) {
CurDisplay->ds_LastRefreshTop = ++CurDisplay->ds_WindowTop;
ScrScrollup();
RefreshHunks(1, 0, CurDisplay->ds_WindowTop + ScrMainBodyRange(NULL,NULL) - 1);
return TRUE;
}
BOOL UpHunks(void) {
if (CurDisplay->ds_WindowTop) {
CurDisplay->ds_LastRefreshTop = --CurDisplay->ds_WindowTop;
ScrScrolldown();
RefreshHunks(1, 0, CurDisplay->ds_WindowTop);
}
return TRUE;
}
WORD RefreshHunks(WORD maxLines, BOOL fullRefresh, LONG index) {
WORD count = 0;
HUNK *thisHunk;
DEBUG *debug;
ULONG hunkNum;
do_scroller();
if (fullRefresh) {
SetTitle(NULL,NULL);
// add a separation line between hunks and register display
if(CurDisplay->ds_RegFlag) {
++count;
Newline();
if (--maxLines == 0)return count;
}
ScrInverse();
ScrPuts("HUNK TYPE SIZE ACTUAL RELOCS SYMBOL LINE");
// xxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
count++;
Newline();
if (--maxLines == 0)return count;
}
ScrPlain();
for (thisHunk = &hunkArray[0], hunkNum = 0; hunkNum < numHunks; hunkNum++, thisHunk++) {
if (index <= 0) {
ScrPrintf("%4d %08X %08X %08X %08X %08X %08X",
hunkNum,
thisHunk->type,
thisHunk->size,
thisHunk->actual,
thisHunk->reloc32,
thisHunk->symbols,
thisHunk->debug
);
count++; ScrPutNewline(); maxLines--; if (!maxLines) return count;
}
--index;
for (debug=thisHunk->debug; debug; debug = debug->link) {
if (index <= 0) {
ScrPrintf(" %08X %s", debug->table[0].address, debug->sourceName);
// xxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
count++;
ScrPutNewline();
maxLines--;
if (!maxLines) return count;
}
--index;
}
}
return count;
}
BOOL UpSymbol(void) {
if (CurDisplay->ds_WindowTop) {
CurDisplay->ds_LastRefreshTop = --CurDisplay->ds_WindowTop;
ScrScrolldown();
RefreshSymbols(1, 0, CurDisplay->ds_WindowTop);
}
return TRUE;
}
BOOL DownSymbol(void) {
CurDisplay->ds_LastRefreshTop = ++CurDisplay->ds_WindowTop;
ScrScrollup();
RefreshSymbols(1, 0, CurDisplay->ds_WindowTop + ScrMainBodyRange(NULL,NULL) - 1);
return TRUE;
}
BOOL PageDownSymbol(void) {
int lines = CalcDisplayLines();
if(lines > 0) {
CurDisplay->ds_WindowTop += lines;
RefreshWindow(1);
}
return TRUE;
}
BOOL PageUpSymbol(void) {
int lines = CalcDisplayLines();
if (CurDisplay->ds_WindowTop) {
if(lines > 0) {
CurDisplay->ds_WindowTop -= lines;
if((LONG)CurDisplay->ds_WindowTop < 0)CurDisplay->ds_WindowTop = 0;
RefreshWindow(1);
}
}
return TRUE;
}
WORD RefreshSymbols(WORD maxLines, BOOL fullRefresh, LONG index) {
ULONG buf[32];
WORD count = 0;
HUNK *thisHunk;
ULONG hunkNum, *symPtr;
ScrPlain();
do_scroller();
if (fullRefresh && maxLines) {
SetTitle(NULL,NULL);
// add a separation line between hunks and register display
if(CurDisplay->ds_RegFlag) {
++count;
Newline();
if (--maxLines == 0)return count;
}
#if 0
ScrInverse();
ScrPuts("ADDRESS SYMBOL VALUES");
// xxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
ScrPlain();
count++;
ScrPutNewline();
if (--maxLines == 0)return TRUE;
#endif
}
for (thisHunk = &hunkArray[0], hunkNum = 0; hunkNum < numHunks; hunkNum++, thisHunk++) {
if (!(symPtr = thisHunk->symbols))continue;
while (*symPtr) {
if (index <= 0) {
ULONG *name = &symPtr[1];
ULONG i = symPtr[0] & 0x00FFFFFF;
for (i = 0; i < symPtr[0]; ++i)buf[i] = name[i];
buf[i] = 0;
if(IsBreakpoint(name[i]))ScrUnderline();
else ScrPlain();
ScrPrintf("%08X %-16.16s", name[i], buf);
--maxLines;
++count;
ScrPutNewline();
if (maxLines == 0)return count;
}
--index;
symPtr = &symPtr[*symPtr + 2];
}
}
return count;
}
/*
*
*
*/
LONG SymbolIndexOfAddr(ULONG val) {
HUNK *thisHunk;
LONG index = 0;
ULONG hunkNum;
ULONG *sym;
if ((sym = NearestSymbol(val)) == NULL)
return 0;
for (thisHunk = &hunkArray[0], hunkNum = 0; hunkNum < numHunks; hunkNum++, thisHunk++) {
ULONG *symPtr;
if ((symPtr = thisHunk->symbols) == NULL)
continue;
// Scan symbols
// [namelen][name][value]
while (*symPtr) {
if (symPtr == sym)
return(index);
symPtr = symPtr + (*symPtr + 2);
++index;
}
}
return 0;
}
// ************************************************************************
#define DPRINTF FALSE
#if DPRINTF
#define dprintf kprintf
#else
#define dprintf //
#endif
ULONG *exeFile;
ULONG exeSize = 0;
ULONG numHunks, firstHunk, lastHunk;
HUNK *hunkArray;
Local BOOL HunkError(ULONG hunkType) {
printf("*** Hunk Error: $%08X\n", hunkType);
return FALSE;
}
BOOL DBugLoadSeg(char *filename) {
int fd;
ULONG i, hunkType, *nextHunk;
HUNK *thisHunk = NULL;
ULONG *exePtr;
ULONG *lasthunk = NULL;
fd = open(filename, O_READ);
if (fd == -1) return FALSE;
exeSize = lseek(fd, 0, 2); lseek(fd, 0, 0);
exeSize += 3; exeSize >>= 2;
exeFile = (ULONG *)MallocPublic(exeSize*4+4);
if (!exeFile) { close(fd); return FALSE; }
read(fd, exeFile, exeSize*4);
close(fd);
exeFile[exeSize] = 0;
exePtr = exeFile;
if (*exePtr != HUNK_HEADER) { Free(exeFile); exeFile = 0; return FALSE; }
while (1) {
hunkType = *exePtr++;
dprintf("HUNK TYPE is %lx == ",hunkType);
switch ( hunkType & 0x3fffffff ) {
case NULL: // 0
dprintf("NULL\n");
return TRUE;
case HUNK_UNIT: // 999
dprintf("HUNK_UNIT\n");
return HunkError(hunkType);
case HUNK_NAME: // 1000
dprintf("HUNK_NAME\n");
return HunkError(hunkType);
case HUNK_CODE: // 1001
#if DPRINTF
dprintf("HUNK_CODE\n");
goto qwe;
#endif
case HUNK_DATA: // 1002
#if DPRINTF
dprintf("HUNK_DATA\n");
goto qwe;
#endif
case HUNK_BSS: // 1003
#if DPRINTF
dprintf("HUNK_BSS\n");
qwe:
#endif
if (!thisHunk) return FALSE;
thisHunk->type = hunkType;
thisHunk->reloc32 = NULL;
thisHunk->debug = NULL;
thisHunk->symbols = NULL;
thisHunk->hSize = *exePtr++;
thisHunk->hunk = exePtr;
if ((thisHunk->type & 0x3fffffff) != HUNK_BSS) {
// skip over code/data section
exePtr = &exePtr[thisHunk->hSize];
}
i = (thisHunk->size << 2) + 4 ; // size of hunk in bytes
// (inc. next hunk link)
// special new memory allocation defined in 2.04 AmigaDOS
if (((thisHunk->type & ((1<<31)|(1<<30))) == ((1<<31)|(1<<30)))) { // any
ULONG memtype = (*exePtr++) & 0x00FFFFFF;
thisHunk->memptr = (ULONG *)MallocAny(i,memtype);
}
else if (thisHunk->type & (1<<31)) { // fast
thisHunk->memptr = (ULONG *)MallocFast(i);
}
else if (thisHunk->type & (1<<30)) { // chip
thisHunk->memptr = (ULONG *)MallocChip(i);
}
else { // public
thisHunk->memptr = (ULONG *)MallocPublic(i);
}
if (!thisHunk->memptr) {
printf("*** Can't allocate memory for hunk\n");
return FALSE;
}
// skip past the link to next hunk
thisHunk->actual = thisHunk->memptr + 1;
dprintf("Allocation at %lx\n",thisHunk->actual);
// check Scroller Range Settings
if((thisHunk->type & 0x3fffffff) == HUNK_CODE) {
if((ULONG)thisHunk->actual < ScrollStart)
ScrollStart = (unsigned long)thisHunk->actual;
if((ULONG)(thisHunk->actual + i/4) > ScrollEnd)
ScrollEnd = (unsigned long)thisHunk->actual + i/4;
}
// store the link to this hunk in the previous hunk
if(lasthunk) {
*lasthunk = MKBADDR((ULONG *)thisHunk->memptr);
}
lasthunk = thisHunk->memptr;
break;
case HUNK_RELOC32: // 1004
dprintf("HUNK_RELOC32\n");
if (!thisHunk) return FALSE;
thisHunk->reloc32 = exePtr;
while (i = *exePtr++) exePtr = &exePtr[i+1];
break;
case HUNK_RELOC16: // 1005
dprintf("HUNK_RELOC16\n");
return HunkError(hunkType);
case HUNK_RELOC8: // 1006
dprintf("HUNK_RELOC8\n");
return HunkError(hunkType);
case HUNK_EXT: // 1007
dprintf("HUNK_EXT\n");
return HunkError(hunkType);
case HUNK_SYMBOL: // 1008
dprintf("HUNK_SYMBOL\n");
if (!thisHunk) return FALSE;
thisHunk->symbols = exePtr;
while (i = *exePtr++) {
exePtr = &exePtr[i];
*exePtr += (ULONG)thisHunk->actual;
exePtr++;
}
break;
case HUNK_DEBUG: // 1009
dprintf("HUNK_DEBUG\n");
if (!thisHunk) return FALSE;
i = *exePtr++;
nextHunk = &exePtr[i];
i = (ULONG)thisHunk->actual;
i += *exePtr++; // address that offsets in table are from
if (*exePtr++ == 'LINE') {
DEBUG *dbg = (DEBUG *)MallocPublic(sizeof(DEBUG));
ULONG base = i, *pl;
if (!dbg) {
printf("Can't allocate DEBUG structure\n");
exit(20);
}
dbg->link = thisHunk->debug;
thisHunk->debug = dbg;
for (i=0; i<128; i++) dbg->sourceName[i] = '\0';
i = *exePtr++; // length of filename in longs
pl = (ULONG *)&dbg->sourceName[0];
while (i > 0) { *pl++ = *exePtr++; --i; }
dbg->table = (SOURCE *)exePtr;
dbg->tableEnd = (SOURCE *)nextHunk;
// read in the source file
dbg->source = NULL;
{
int fd = open(dbg->sourceName, O_READ);
if (fd != -1) {
i = lseek(fd, 0, 2); lseek(fd, 0, 0);
dbg->source = (char *)MallocPublic(i+1);
if (dbg->source) {
read(fd, dbg->source, i);
dbg->source[i] = '\0';
}
close(fd);
}
}
// relocate line#/offset pair table
// determine bounds of debugger hunk
// XXX can miss code inbetween linked
// object modules, addresses are
// not right up against each other
{
SOURCE *ps;
for (ps = dbg->table; ps != dbg->tableEnd; ps++)
ps->address += base;
if (ps != dbg->table) {
dbg->addrBegin = dbg->table->address;
dbg->addrEnd = (ps-1)->address;
}
}
}
exePtr = nextHunk;
break;
case HUNK_END: // 1010
dprintf("HUNK_END\n");
thisHunk++;
break;
case HUNK_HEADER: // 1011
dprintf("HUNK_HEADER\n");
while (i = *exePtr++) exePtr = &exePtr[i]; // skip libs
numHunks = *exePtr++;
firstHunk = *exePtr++;
lastHunk = *exePtr++;
hunkArray = (HUNK *)MallocPublic(sizeof(HUNK) * numHunks);
if (!hunkArray) {
printf("*** Insufficient memory for HunkHeader table\n");
exit(20);
}
// fetch hunk sizes from the header and store in hunkArray
for (i=0; i<numHunks; i++) hunkArray[i].size = *exePtr++;
thisHunk = hunkArray;
break;
// case HUNK_INVALID: // 1012
//dprintf("case HUNK_INVALID\n");
// return HunkError(hunkType);
case HUNK_OVERLAY: // 1013
dprintf("HUNK_OVERLAY\n");
return HunkError(hunkType);
case HUNK_BREAK: // 1014
dprintf("HUNK_BREAK\n");
return HunkError(hunkType);
case HUNK_DREL32: // 1015
dprintf("HUNK_DREL32\n");
return HunkError(hunkType);
case HUNK_DREL16: // 1016
dprintf("HUNK_DREL16\n");
return HunkError(hunkType);
case HUNK_DREL8: // 1017
dprintf("HUNK_DREL8\n");
return HunkError(hunkType);
case HUNK_LIB: // 1018
dprintf("HUNK_LIB\n");
return HunkError(hunkType);
case HUNK_INDEX: // 1019
dprintf("HUNK_INDEX\n");
return HunkError(hunkType);
default:;
dprintf("Unknown hunk type %lx\n",hunkType);
break;
}
}
}
void AllocateStack(void) {
if (!programStack) {
// reset stack size to CLI stack size if CLU default
// stack is larger than 32K
programStackSize = MAX(thisCli->cli_DefaultStack * 4, programStackSize);
programStack = (UBYTE *)MallocPublic(programStackSize);
if(!programStack) {
printf("Can't Allocate Program Stack!\n");
exit(20);
}
programStackTop = &programStack[programStackSize];
}
}
void ResetTarget(void) {
HUNK *thisHunk = &hunkArray[0];
ULONG i;
struct FileHandle *fh;
char *pd;
AllocateStack();
for (i=0; i<numHunks; i++, thisHunk++) {
switch (thisHunk->type & 0x3fffffff) {
// code and data hunks are copied from the file into allocated memory.
// then the reloc32 hunk is applied to relocate the copied hunk.
case HUNK_CODE:
case HUNK_DATA: { // copy the hunk
ULONG *ps = thisHunk->hunk, *pd = thisHunk->actual;
ULONG i = thisHunk->hSize;
while (i > 0) {
*pd++ = *ps++;
--i;
}
}
{ // relocations
UBYTE *base = (UBYTE *)thisHunk->actual;
ULONG offset, *src = thisHunk->reloc32;
ULONG hunkNumber, numRelocs;
if (!src) break; // no reloc32 hunk
numRelocs = *src++;
while (numRelocs) {
hunkNumber = *src++;
offset = (ULONG)hunkArray[hunkNumber].actual;
while (numRelocs) {
*(ULONG *)&base[*src++] += offset;
numRelocs--;
}
numRelocs = *src++;
}
}
break;
case HUNK_BSS:
break;
default:;
dprintf("UNKNOWN HUNK in RESET\n");
break;
}
}
// Load Input() with command line, if any
// (A debugger has to do shell like things, occasionally
if((fh = (struct FileHandle *)BADDR(Input()))) {
Flush(Input());
pd = (char *)BADDR(fh->fh_Buf);
strcpy(pd,"");
strncat(pd,args,argSize-1);
strcat(pd,"\n");
fh->fh_Pos = 0;
fh->fh_End = strlen(pd);
}
// initialize registers
lastState = programState = STATE_RESET;
lastPC = programPC = (ULONG)hunkArray[0].actual;
lastSR = programSR = 0;
lastA0 = programA0 = (ULONG)args;
lastD0 = programD0 = argSize;
lastD1 = lastD2 = lastD3 = lastD4 = lastD5 = lastD6 = lastD7 =
programD1 = programD2 = programD3 = programD4 = programD5 = programD6 = programD7 = 0;
lastA1 = lastA2 = lastA3 = lastA4 = lastA5 = lastA6 =
programA1 = programA2 = programA3 = programA4 = programA5 = programA6 = 0;
programA7 = (ULONG)&programStack[programStackSize];
// BCPL programs are going to want A1, A2, A5, and A6 to be
// set up properly. The easiest place to get this is from
// our own stack
{
long *stacktop;
long *clistack;
// get pointer to top of our stack
stacktop = ((struct Process *)(SysBase->ThisTask))->pr_ReturnAddr;
// get last value of CLI stack
clistack = (long *) *(++stacktop);
lastA1 = programA1 =(ULONG)(*(++clistack));
lastA2 = programA2 =(ULONG)(*(++clistack));
lastA5 = programA5 =(ULONG)(*(++clistack));
lastA6 = programA6 =(ULONG)(*(++clistack));
{ // push "catcher" address on program stack
ULONG *a7 = (ULONG *)programA7;
--a7; // put half the stack size (in longs) on stack
*a7 = programStackSize/4;
--a7;
*a7 = (ULONG)TargetExit;
lastA7 = programA7 = (ULONG)a7;
}
}
if (LookupSymbol("@main", &i) || LookupSymbol("_main", &i)) {
SetTempBreakpoint(i);
GoTarget();
}
CurDisplay->ds_WindowTop = programPC;
CurDisplay->ds_WindowTopLine = 0;
// set the default save address tables
SetModeSave(DISPLAY_BYTES);
SetModeSave(DISPLAY_SOURCE);
}
DEBUG *FindDebug(ULONG address) {
DEBUG *debug;
SOURCE *source;
if (debug = FindNearestDebug(address)) {
for (source = debug->table; source != debug->tableEnd; ++source) {
if (source->address == address)break;
}
debug = NULL;
}
return(debug);
}
#ifdef NOTDEF // REMOVED
DEBUG *FindDebug(ULONG address) {
HUNK *thisHunk;
ULONG hunkNum, hunkStart, hunkEnd;
DEBUG *debug;
SOURCE *source;
for (thisHunk = &hunkArray[0], hunkNum = 0; hunkNum < numHunks; thisHunk++, hunkNum++) {
hunkStart = (ULONG)thisHunk->actual; hunkEnd = hunkStart + (thisHunk->size<<2);
if (address < hunkStart || address > hunkEnd) continue;
debug = thisHunk->debug;
while (debug) {
source = debug->table;
while (source != debug->tableEnd) {
if (source->address == address) return debug;
source++;
}
debug = debug->link;
}
}
return NULL;
}
#endif
DEBUG *FindNearestDebug(ULONG address) {
HUNK *thisHunk;
ULONG hunkNum, hunkStart, hunkEnd;
DEBUG *debug;
for (thisHunk = &hunkArray[0], hunkNum = 0; hunkNum < numHunks; thisHunk++, hunkNum++) {
hunkStart = (ULONG)thisHunk->actual; hunkEnd = hunkStart + (thisHunk->size<<2);
if (address < hunkStart || address > hunkEnd) continue;
for (debug = thisHunk->debug; debug; debug = debug->link) {
if (address >= debug->addrBegin && address <= debug->addrEnd)
return(debug);
}
}
return NULL;
}
SOURCE *FindSource(DEBUG *debug, ULONG address) {
SOURCE *source;
source = debug->table;
if (source) {
while (source != debug->tableEnd) {
if (source->address == address) return source;
source++;
if (source != debug->tableEnd && source->address > address) {
--source;
return source;
}
}
}
return NULL;
}
char *FindSourceLine(DEBUG *debug, SOURCE *source) {
char *line = debug->source;
ULONG currentLine = 1;
if(line) {
while (currentLine < source->lineNumber) {
while (*line && (*line != '\n')) {
*line++;
}
if (*line) line++;
currentLine++;
}
if (*line) return line;
}
return NULL;
}
__stkargs char *LookupValue(ULONG value) {
HUNK *thisHunk;
ULONG i, hunkNum, *symPtr, *name;
ULONG hunkStart, hunkEnd;
ULONG *ps, *pd;
static ULONG symBuf[64];
for (thisHunk = &hunkArray[0], hunkNum = 0; hunkNum < numHunks;
thisHunk++, hunkNum++) {
hunkStart = (ULONG)thisHunk->actual; hunkEnd = hunkStart + (thisHunk->size<<2);
if (value < hunkStart || value > hunkEnd) continue;
symPtr = thisHunk->symbols;
if (!symPtr) return NULL;
while (*symPtr) {
name = symPtr;
i = *symPtr++;
symPtr = &symPtr[i];
if (*symPtr++ == value) {
for (i=0; i<64; i++) symBuf[i] = 0;
pd = &symBuf[0];
i = *name++;
ps = name;
while (i > 0) { *pd++ = *ps++; --i; }
return (char *)&symBuf[0];
}
}
return LookupOffset(value,symBuf); // return NULL;
}
return LookupOffset(value,symBuf); // return NULL;
}
char *LookupOffset(ULONG value,ULONG *symBuf) {
char *s;
ULONG val;
if(CurDisplay->ds_DisplayOffsets) {
if(s = NearestValue(value)) {
LookupSymbol(s,&val);
sprintf((char *)&symBuf[0],"%s + $%04X",s,value-val);
return (char *)&symBuf[0];
}
}
return NULL;
}
ULONG *NearestSymbol(ULONG value) {
HUNK *thisHunk;
ULONG i, hunkNum, *symPtr, *name, diff = 0x7fffffff, *found;
ULONG hunkStart, hunkEnd;
found = NULL;
for (thisHunk = &hunkArray[0], hunkNum = 0; hunkNum < numHunks; thisHunk++, hunkNum++) {
hunkStart = (ULONG)thisHunk->actual; hunkEnd = hunkStart + (thisHunk->size<<2);
if (value < hunkStart || value > hunkEnd) continue;
symPtr = thisHunk->symbols;
if (!symPtr) return NULL;
while (*symPtr) {
name = symPtr;
i = *symPtr++;
symPtr = &symPtr[i];
if (*symPtr == value) { found = name; break; }
if (*symPtr < value && value - *symPtr < diff) { found = name; diff = value - *symPtr; }
symPtr++;
}
return found;
}
return NULL;
}
char *NearestValue(ULONG value) {
ULONG *found;
ULONG *ps, *pd;
LONG i;
static ULONG symBuf[64];
if (found = NearestSymbol(value)) {
for (i=0; i<64; i++) symBuf[i] = 0;
pd = &symBuf[0];
i = *found++;
ps = found;
while (i > 0) { *pd++ = *ps++; --i; }
return (char *)&symBuf[0];
}
return(NULL);
}
#ifdef NOTDEF
//
// REMOVED
//
char *NearestValue(ULONG value) {
HUNK *thisHunk;
ULONG i, hunkNum, *symPtr, *name, diff = 0x7fffffff, *found;
ULONG hunkStart, hunkEnd;
ULONG *ps, *pd;
static ULONG symBuf[64];
found = NULL;
for (thisHunk = &hunkArray[0], hunkNum = 0; hunkNum < numHunks; thisHunk++, hunkNum++) {
hunkStart = (ULONG)thisHunk->actual; hunkEnd = hunkStart + (thisHunk->size<<2);
if (value < hunkStart || value > hunkEnd) continue;
symPtr = thisHunk->symbols;
if (!symPtr) return NULL;
while (*symPtr) {
name = symPtr;
i = *symPtr++;
symPtr = &symPtr[i];
if (*symPtr == value) { found = name; break; }
if (*symPtr < value && value - *symPtr < diff) { found = name; diff = value - *symPtr; }
symPtr++;
}
if (found) {
for (i=0; i<64; i++) symBuf[i] = 0;
pd = &symBuf[0];
i = *found++;
ps = found;
while (i > 0) { *pd++ = *ps++; --i; }
return (char *)&symBuf[0];
}
return NULL;
}
return NULL;
}
#endif
Local BOOL CompareLStrings(ULONG *s1, ULONG *s2) {
ULONG len = *s1++;
if (len != *s2++) return FALSE;
while (len > 0) {
if (*s1++ != *s2++) return FALSE;
len--;
}
return TRUE;
}
int CountSymbols(void) {
HUNK *thisHunk;
ULONG i, hunkNum, *symPtr;
int symcount = 0;
for(thisHunk= &hunkArray[0],hunkNum=0;hunkNum < numHunks;
thisHunk++,hunkNum++){
symPtr = thisHunk->symbols;
if (!symPtr) continue;
while (*symPtr) {
i = *symPtr++;
symPtr = &symPtr[i];
symPtr++;
symcount++;
}
}
return symcount;
}
BOOL LookupSymbol(char *symbol, ULONG *value) {
HUNK *thisHunk;
ULONG i, hunkNum, *symPtr, *name;
UBYTE *ps, *pd;
ULONG symBuf[64];
for (i=0; i<64; i++) {
symBuf[i] = 0;
}
ps = (UBYTE *)symbol;
pd = (UBYTE *)&symBuf[1];
i = 0;
while (*pd++ = *ps++) i++;
i += 3;
i /= 4;
symBuf[0] = i;
for(thisHunk= &hunkArray[0],hunkNum=0;hunkNum < numHunks;
thisHunk++,hunkNum++){
symPtr = thisHunk->symbols;
if (!symPtr) continue;
while (*symPtr) {
name = symPtr;
i = *symPtr++;
symPtr = &symPtr[i];
if (CompareLStrings(symBuf, name)) {
*value = *symPtr;
return TRUE;
}
symPtr++;
}
}
return FALSE;
}
void CopySymbols(SYMLIST *symlist) {
HUNK *thisHunk;
ULONG i, hunkNum, *symPtr, *name;
int j = 0;
for(thisHunk= &hunkArray[0],hunkNum=0;hunkNum < numHunks; thisHunk++,hunkNum++){
symPtr = thisHunk->symbols;
if (!symPtr) continue;
while (*symPtr) {
name = symPtr;
i = *symPtr++;
symPtr = &symPtr[i];
symlist[j].symbolname = name;
symlist[j].address = *symPtr;
j++;
symPtr++;
}
}
}
BOOL LookupSymLen(char *symbol, UWORD len, ULONG *value) {
HUNK *thisHunk;
ULONG i, hunkNum, *symPtr, *name;
UBYTE *ps, *pd;
ULONG symBuf[64];
ps = (UBYTE *)symbol; pd = (UBYTE *)&symBuf[1];
for (i=0; i<64; i++) symBuf[i] = 0;
for (i = 0; i<len; i++) *pd++ = *ps++;
*pd = '\0';
i += 3;
i /= 4;
symBuf[0] = i;
for (thisHunk = &hunkArray[0], hunkNum = 0; hunkNum < numHunks; thisHunk++, hunkNum++) {
symPtr = thisHunk->symbols;
if (!symPtr) continue;
while (*symPtr) {
name = symPtr;
i = *symPtr++;
symPtr = &symPtr[i];
if (CompareLStrings(symBuf, name)) {
*value = *symPtr;
return TRUE;
}
symPtr++;
}
}
return FALSE;
}
char *addscore(char *string)
{
static char buffer[256];
strcpy(&buffer[1],string);
buffer[0]='_';
return buffer;
}
char *addat(char *string)
{
static char buffer[256];
strcpy(&buffer[1],string);
buffer[0]='@';
return buffer;
}